home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / xgrabsc / get.hc < prev    next >
Text File  |  1995-05-09  |  8KB  |  286 lines

  1. /*========================================================================
  2.  *
  3.  * Name - get.hc
  4.  *
  5.  * ccs version:    1.4
  6.  *
  7.  * ccsid:    @(#)get.hc    1.4 - 11/03/92 14:55:59
  8.  * from:     ccs/s.get.hc
  9.  * date:     06/28/93 09:14:48
  10.  *
  11.  * Description:  image grabbing functions for xgrabsc
  12.  *
  13.  *               see cpyright.h for copyright information
  14.  *
  15.  *
  16.  *========================================================================
  17.  */
  18.  
  19. /*
  20.  * Get the image bounded by the given rectangle.
  21.  * The associated colormap information is also extracted and returned.
  22.  * TRUE is returned if an image was successfully grabbed, and FALSE
  23.  * otherwise.
  24.  */
  25. getImage(xrect, image, window, cmapwindow)
  26.   XRectangle *xrect;
  27.   imageInfo *image;
  28.   Window window, cmapwindow;
  29. {
  30.   XImage *ximage;
  31.   int depth, ncolors, cmapSize, numCmaps;
  32.   int h, w;
  33.   long i;
  34.   XColor colors[MAX_CELLS];
  35.   Colormap *cmaps, cmap;
  36.  
  37.   if (xrect->width == 0  || xrect->height == 0)
  38.     return FALSE;
  39.  
  40.   /* get the image */
  41.   depth  = DefaultDepth(hDisplay, hScreen);
  42.   ximage = XGetImage(hDisplay, window,
  43.             xrect->x, xrect->y, xrect->width, xrect->height, AllPlanes,
  44.             depth==1 ? XYPixmap : ZPixmap);
  45.   image->ximage = ximage;
  46.  
  47.   /* get the colormap info */
  48.   if (cmapwindow != (Window)NULL)
  49.     cmaps = XListInstalledColormaps(hDisplay, cmapwindow, &numCmaps);
  50.   else
  51.     cmaps = XListInstalledColormaps(hDisplay, window, &numCmaps);
  52.  
  53.   if (numCmaps == 0)
  54.     cmap = DefaultColormap(hDisplay, hScreen);
  55.   else {
  56.     cmap = *cmaps;
  57.     if (numCmaps > 1)
  58.       fprintf(stderr,
  59.         "%s: more than one colormap found - using first encountered",
  60.         programName);
  61.   }
  62.   XFree(cmaps);
  63.  
  64.   ncolors = DisplayCells(hDisplay, hScreen);
  65.   /* this won't cut the mustard for DirectColor */
  66.   for (i=0; i<ncolors; i++)
  67.     colors[i].pixel = i;
  68.  
  69.   XQueryColors(hDisplay, cmap, colors, ncolors);
  70.   for (i=0; i<ncolors; i++) {
  71.     image->red[i]   = colors[i].red;
  72.     image->green[i] = colors[i].green;
  73.     image->blue[i]  = colors[i].blue;
  74.   }
  75.  
  76.   /* figure out which colormap entries are actually used by the image */
  77.   ncolors = cmapSize = 0;
  78.   memset((char *)image->used, 0, MAX_CELLS);
  79.   for (h=0; h<ximage->height; h++)
  80.     for (w=0; w<ximage->width; w++) {
  81.       i = XGetPixel(ximage, w, h);
  82.       if (!image->used[i]) {
  83.         image->used[i] = TRUE;
  84.         if (i+1 > cmapSize)      /* keep track of colormap size */
  85.           cmapSize = i+1;
  86.         ncolors++;
  87.       }
  88.     }
  89.   image->numcells = cmapSize;
  90.   if (verbose)
  91.     fprintf(stderr, "%s: image has %d colors\n", programName, ncolors);
  92.  
  93.   return TRUE;
  94. }
  95.  
  96.  
  97.  
  98. /*
  99.  * Let the user stretch a rectangle on the screen and return its values.
  100.  * It may be wise to grab the server before calling this routine.  If the
  101.  * screen is allowed to change during XOR drawing video droppings may result.
  102.  */
  103. getRectangle(xrect)
  104.   XRectangle *xrect;
  105. {
  106.   XEvent event;
  107.   unsigned int x, y, rootx, rooty;
  108.   GC gc;
  109.   Cursor pointer1, pointer2;
  110.   int boxDrawn = False;
  111.   int rx, ry, rw, rh;
  112.  
  113.   /* get some cursors for rectangle formation */
  114.   pointer1 = XCreateFontCursor(hDisplay, XC_ul_angle);
  115.   pointer2 = XCreateFontCursor(hDisplay, XC_lr_angle);
  116.  
  117.   /* grab the pointer */
  118.   if (GrabSuccess != XGrabPointer(hDisplay, hRoot, False, ButtonPressMask,
  119.         GrabModeAsync, GrabModeAsync, hRoot, pointer1, CurrentTime)) {
  120.     fprintf(stderr,"%s - could not grab pointer!\n", programName);
  121.     exit(3);
  122.   }
  123.  
  124.   /* create a graphics context to draw with */
  125.   gc = XCreateGC(hDisplay, hRoot, 0, NULL);
  126.   if (!gc) {
  127.     fprintf(stderr,"%s - could not get drawing resources\n", programName);
  128.     exit(3);
  129.   }
  130.   XSetSubwindowMode(hDisplay, gc, IncludeInferiors);
  131.   XSetForeground(hDisplay, gc, 255);
  132.   XSetFunction(hDisplay, gc, GXxor);
  133.  
  134.   /* get a button-press and pull out the root location */
  135.   XMaskEvent(hDisplay, ButtonPressMask, &event);
  136.   rootx = rx = event.xbutton.x_root;
  137.   rooty = ry = event.xbutton.y_root;
  138.  
  139.   /* get pointer motion events */
  140.   XChangeActivePointerGrab(hDisplay, ButtonMotionMask | ButtonReleaseMask,
  141.         pointer2, CurrentTime);
  142.  
  143.  
  144.   /* MAKE_RECT converts the original root coordinates and the event root
  145.    * coordinates into a rectangle in xrect */
  146. #define MAKE_RECT(etype) \
  147.   x = event.etype.x_root;       \
  148.   y = event.etype.y_root;       \
  149.   rw  = x - rootx;              \
  150.   if (rw  < 0) rw  = -rw;       \
  151.   rh  = y - rooty;              \
  152.   if (rh  < 0) rh  = -rh;       \
  153.   rx = x < rootx ? x : rootx;   \
  154.   ry = y < rooty ? y : rooty
  155.  
  156.   /* loop to let the user drag a rectangle */
  157.   while (TRUE) {
  158.     XNextEvent(hDisplay, &event);
  159.     switch(event.type) {
  160.       case ButtonRelease:
  161.         if (boxDrawn) {
  162.           XDrawRectangle(hDisplay, hRoot, gc, rx, ry, rw, rh);
  163.           boxDrawn = False;
  164.         }
  165.         XFlush(hDisplay);
  166.         /* record the final location */
  167.         MAKE_RECT(xbutton);
  168.         /* release resources */
  169.         XFreeGC(hDisplay, gc);
  170.         XFreeCursor(hDisplay, pointer1);
  171.         XFreeCursor(hDisplay, pointer2);
  172.         xrect->x      = rx;
  173.         xrect->y      = ry;
  174.         xrect->width  = rw;
  175.         xrect->height = rh;
  176.         XUngrabPointer(hDisplay, CurrentTime);
  177.     XSync(hDisplay, FALSE);
  178.         return True;
  179.       case MotionNotify:
  180.         if (boxDrawn) {
  181.           XDrawRectangle(hDisplay, hRoot, gc, rx, ry, rw, rh);
  182.           boxDrawn = False;
  183.         }
  184.         while (XCheckTypedEvent(hDisplay, MotionNotify, &event))
  185.           {}
  186.         MAKE_RECT(xmotion);
  187.         XDrawRectangle(hDisplay, hRoot, gc, rx, ry, rw, rh);
  188.         boxDrawn = True;
  189.         break;
  190.     }
  191.   }
  192. }
  193.  
  194.  
  195.  
  196.  
  197.  
  198.  
  199. /*
  200.  * find the window under the mouse pointer when one of the bits in keyMask
  201.  * is satisfied.
  202.  */
  203. Window getWindowWhenKeyIsPressed(keyMask)
  204.   unsigned int keyMask;
  205. {
  206.   Bool status;
  207.   Window result;
  208.   Window root, child;
  209.   int root_x, root_y, win_x, win_y;
  210.   unsigned int keys_buttons;
  211.  
  212.   if (verbose)
  213.     fprintf(stderr, "%s: waiting for keypress\n", programName);
  214.  
  215.   do {
  216.     status = XQueryPointer(hDisplay, vRoot, &root, &child,
  217.               &root_x, &root_y, &win_x, &win_y, &keys_buttons);
  218.     if (!status)
  219.       return (Window)0;
  220.   } while ((keyMask != 0) && ((keyMask & keys_buttons) == 0));
  221.  
  222.   if (child == (Window)0) {
  223.     if (verbose) {
  224.       fprintf(stderr, "%s: unable to find a non-root window under pointer.\n",
  225.               programName);
  226.       fprintf(stderr, "%s: using root window.\n", programName);
  227.     }
  228.     result = (Window)vRoot;
  229.   }
  230.   else
  231.     result = child;
  232.  
  233.   if (verbose)
  234.     fprintf(stderr, "%s: returning window id %d\n", programName, result);
  235.  
  236.   return result;
  237. }
  238.  
  239.  
  240.  
  241.  
  242. /*
  243.  * choose a window as in xwd
  244.  */
  245.  
  246. Window getWindow() {
  247.   int status;
  248.   Cursor cursor;
  249.   XEvent event;
  250.   Window result;
  251.  
  252.   result = None;
  253.  
  254.   cursor = XCreateFontCursor(hDisplay, XC_target);
  255.  
  256.   status = XGrabPointer(hDisplay, vRoot, FALSE,
  257.          ButtonPressMask|ButtonReleaseMask, GrabModeSync,
  258.          GrabModeAsync, hRoot, cursor, CurrentTime);
  259.   if (status != GrabSuccess) {
  260.     fprintf(stderr, "%s: can't grab mouse\n", programName);
  261.     exit(3);
  262.   }
  263.  
  264.   while (TRUE) {
  265.     XAllowEvents(hDisplay, SyncPointer, CurrentTime);
  266.     XWindowEvent(hDisplay, vRoot, ButtonPressMask|ButtonReleaseMask, &event);
  267.  
  268.     switch (event.type) {
  269.       case ButtonRelease:
  270.         result = event.xbutton.subwindow;
  271.         if (result == None)
  272.           result = hRoot;
  273.         XUngrabPointer(hDisplay, CurrentTime);      /* Done with pointer */
  274.         if (verbose)
  275.           fprintf(stderr, "%s: found window with id 0x%x\n", programName, result);
  276.         return result;
  277.         break;
  278.     }
  279.   }
  280.  
  281. }
  282.  
  283.  
  284.  
  285.  
  286.